package com.thinkgem.jeesite.common.web;

import com.google.common.collect.Lists;
import com.thinkgem.jeesite.common.ConstantEnum;
import com.thinkgem.jeesite.common.beanvalidator.BeanValidators;
import com.thinkgem.jeesite.common.persistence.ActEntity;
import com.thinkgem.jeesite.common.persistence.DataEntity;
import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.persistence.ReturnObject;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.Reflections;
import com.thinkgem.jeesite.common.utils.excel.ExportExcel;
import com.thinkgem.jeesite.common.utils.excel.ImportExcel;
import com.thinkgem.jeesite.modules.sys.service.SystemService;
import com.thinkgem.jeesite.modules.teach.entity.TpTeachAchievement;

import com.thinkgem.jeesite.modules.teach.entity.TpTeachActive;
import com.thinkgem.jeesite.modules.teach.service.TpTeachActiveService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

/**
 * 含有导入导出的Controller
 */
public abstract class ExcelController<T extends ActEntity<T>> extends  BaseController<T>{


    public abstract String getTitle();

    public abstract String defaultStr();

    public abstract CrudService baseService();

    @Autowired
    private SystemService  systemService;




    /**
     * 下载导入数据模板
     * @param response
     * @param redirectAttributes
     * @return
     */
    public String importFileTemplate(HttpServletResponse response, RedirectAttributes redirectAttributes,T t) {
        try {
            List<T> list = Lists.newArrayList();list.add(t);
            new ExportExcel(getTitle(), t.getClass(), 2).setDataList(list).write(response,getTitle()+"模板.xlsx").dispose();
            return null;
        } catch (Exception e) {
            addMessage(redirectAttributes, "导入模板下载失败！失败信息："+e.getMessage());
        }
        return null;
    }
    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes,T data){
        return importFile(file,redirectAttributes,data,true);
    }

    /**
     * 导入
     * @param file
     * @param redirectAttributes
     * @return
     */
    public String importFile(MultipartFile file, RedirectAttributes redirectAttributes,T data,boolean flag) {
        try {
            int successNum = 0;
            int failureNum = 0;
            StringBuilder failureMsg = new StringBuilder();
            ImportExcel ei = new ImportExcel(file, 1, 0);
            List<T> list = (List<T>) ei.getDataList(data.getClass());
            int n=0;
            systemService.setFieldId(list);
            for (T t : list){
                n++;
                try{
                	//默认审核通过
                    if(flag)
                	Reflections.invokeSetter(t, "status", 2);
                    BeanValidators.validateWithException(validator, t);
                    if(baseService() instanceof TpTeachActiveService&& t instanceof TpTeachActive){
                        TpTeachActiveService ttas=(TpTeachActiveService)baseService();
                        if(ttas.saves((TpTeachActive)t)<=0)
                            failureMsg.append("<br/>第： "+n+" 行数据导入失败：数据已存在");
                    }else{
                        baseService().save(t);
                    }
                    successNum++;
                }catch(ConstraintViolationException ex){
                	ex.printStackTrace();
                    failureMsg.append("<br/>第： "+n+" 行数据导入失败：");
                    List<String> messageList = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
                    for (String message : messageList){
                        failureMsg.append(message+"; ");
                        failureNum++;
                    }
                }catch (Exception ex) {
                	ex.printStackTrace();
                    failureMsg.append("<br/>第： "+n+" 行数据导入失败："+ex.getMessage());
                }
            }
            if (failureNum>0){
                failureMsg.insert(0, "，失败 "+failureNum+" 条记录，导入信息如下：");
            }
            addMessage(redirectAttributes, "已成功导入 "+successNum+" 条记录"+failureMsg);
        } catch (Exception e) {
        	e.printStackTrace();
            addMessage(redirectAttributes, "导入记录失败！失败信息："+e.getMessage());
        }
        return "redirect:" + adminPath + defaultStr();
    }
    /**
     * 导出数据
     * @param request
     * @param response
     * @param redirectAttributes
     * @return
     */
    public String exportFile(T t, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
        try {
            String fileName = getTitle()+ DateUtils.getDate("yyyy-MM-dd")+".xlsx";
            //Page<T> page = baseService().findPage(new Page<T>(request, response, -1), t);
            List<T> data = baseService().findList(t);
            new ExportExcel(getTitle(),t.getClass()).setDataList(data).write(response, fileName).dispose();
            return null;
        } catch (Exception e) {
            addMessage(redirectAttributes, "导出记录失败！失败信息："+e.getMessage());
        }
        return null;
    }
    public String exportFile(T t,int type, HttpServletRequest request, HttpServletResponse response, RedirectAttributes redirectAttributes) {
    	try {
    		String fileName = getTitle()+ DateUtils.getDate("yyyy-MM-dd")+".xlsx";
    		//Page<T> page = baseService().findPage(new Page<T>(request, response, -1), t);
    		List<T> data = baseService().findList(t);
    		new ExportExcel(getTitle(),t.getClass(),type).setDataList(data).write(response, fileName).dispose();
    		return null;
    	} catch (Exception e) {
    		addMessage(redirectAttributes, "导出记录失败！失败信息："+e.getMessage());
    	}
    	return null;
    }
    @RequestMapping(value="getInfoById")
    @ResponseBody
    public Object getInfoById(String id ){
    	ReturnObject rtobj = new ReturnObject();
		rtobj.setResult(ConstantEnum.success.getCode());
		rtobj.setMsg(ConstantEnum.success.getName());
		T data =  (T) baseService().get(id);
		ExportExcel ex = new ExportExcel("",data.getClass());
		data = ex.getMobileDataList(data);
		data.setPropertyNameMap(ex.getPropertyNameMap());
		rtobj.setData(data);
		return rtobj;
    	
    }

    /**
     * 批量删除
     * @param idArr
     * @param t
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "/batchDelete", method= RequestMethod.POST)
    public String batchDelete(@RequestParam("idArr") List<String> idArr, T t, RedirectAttributes redirectAttributes) {
        try {
            List<T> entitys = new ArrayList<>();
            for(String id:idArr){
                T entity = (T) t.getClass().newInstance();
                entity.setId(id);
                entitys.add(entity);
            }
            baseService().batchDelete(entitys);
        } catch (Exception e) {
            addMessage(redirectAttributes, "批量删除失败！失败信息："+e.getMessage());
        }
        return "redirect:" + adminPath + defaultStr();
    }
}
